package cn.xy.base.server.controller.admapi;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.xy.base.server.bean.IPage;
import cn.xy.base.server.dto.SysRoleAddDTO;
import cn.xy.base.server.dto.SysRoleUpdateDTO;
import cn.xy.base.server.enums.RoleEnum;
import cn.xy.base.server.po.SysRole;
import cn.xy.base.server.service.SysPermissionService;
import cn.xy.base.server.service.SysRoleService;
import cn.xy.commons.annotation.OperateLog;
import cn.xy.commons.annotation.RepeatSubmit;
import cn.xy.commons.constant.Consts;
import cn.xy.commons.core.Result;
import cn.xy.commons.enums.DataStatus;
import cn.xy.commons.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

/**
 * 表[sys_role]对应的后台管理类
 *
 * @author auto
 */

@Slf4j
@RestController
@RequestMapping("/admapi/sys/role")
@Api(tags = {"角色管理接口"})
public class SysRoleAdminController {

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPermissionService sysPermissionService;

    @GetMapping("/list")
    @ApiOperation(value = "角色-列表")
    @PreAuthorize("@validate.hasPermission('system-role-list')")
    public Result<Page<SysRole>> list(@RequestParam(required = false, defaultValue = "") String roleName,
                                      IPage page) {
        LambdaQueryWrapper<SysRole> sysRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysRoleLambdaQueryWrapper.like(CharSequenceUtil.isNotEmpty(roleName), SysRole::getRoleName, roleName);
        sysRoleLambdaQueryWrapper.eq(SysRole::getDataStatus, DataStatus.NORMAL.getValue());
        Page<SysRole> pageData = sysRoleService.page(page.toPage(), sysRoleLambdaQueryWrapper);
        return Result.data(pageData);
    }

    @PutMapping("/update")
    @ApiOperation(value = "角色-修改系统角色权限")
    @OperateLog(description = "修改系统角色权限")
    @PreAuthorize("@validate.hasPermission('system-role-update')")
    @RepeatSubmit
    public Result<String> update(@RequestBody @Valid SysRoleUpdateDTO sysRoleUpdateDTO) {
        List<String> permissionsStrList = StringUtil.splitToList(sysRoleUpdateDTO.getPermissions(), Consts.COMMA);
        if (CollUtil.isEmpty(permissionsStrList)) {
            return Result.error("权限列表不能为空");
        }
        SysRole role = sysRoleService.getById(sysRoleUpdateDTO.getId());
        if (role == null) {
            return Result.error(SysRoleService.SYS_ROLE_NOT_EXIST);
        }
        SysRole existRole = sysRoleService.getByRoleName(sysRoleUpdateDTO.getRoleName());
        if (existRole != null && !role.getId().equals(existRole.getId())) {
            return Result.error("角色key值已存在");
        }
        role.setPermissions(String.join(Consts.COMMA, permissionsStrList));
        BeanUtil.copyProperties(sysRoleUpdateDTO, role);
        sysRoleService.updateById(role);
        sysPermissionService.delKeyListCache(role.getId());
        return Result.ok("修改成功");
    }

    @PostMapping("/add")
    @OperateLog(description = "增加系统角色")
    @ApiOperation(value = "角色-增加系统角色")
    @PreAuthorize("@validate.hasPermission('system-role-add')")
    @RepeatSubmit
    public Result<String> add(@RequestBody @Valid SysRoleAddDTO sysRoleAddDTO) {
        List<String> permissionsStrList = StringUtil.splitToList(sysRoleAddDTO.getPermissions(), Consts.COMMA);
        if (CollUtil.isEmpty(permissionsStrList)) {
            return Result.error("权限列表不能为空");
        }
        SysRole role = sysRoleService.getByRoleName(sysRoleAddDTO.getRoleName());
        if (role != null) {
            return Result.error("角色已存在");
        }
        sysRoleAddDTO.setPermissions(String.join(Consts.COMMA, permissionsStrList));
        sysRoleService.save(sysRoleAddDTO.toSysRole());
        return Result.ok("添加成功");
    }

    @DeleteMapping("/delete")
    @OperateLog(description = "删除系统角色")
    @ApiOperation(value = "角色-删除系统角色")
    @PreAuthorize("@validate.hasPermission('system-role-delete')")
    @RepeatSubmit
    public Result<String> delete(int id) {
        if (RoleEnum.roleInEnum(id)) {
            return Result.error("无法删除系统固定角色");
        }
        SysRole role = sysRoleService.getById(id);
        if (role == null) {
            return Result.error(SysRoleService.SYS_ROLE_NOT_EXIST);
        }
        sysRoleService.removeById(id);
        sysPermissionService.delKeyListCache(role.getId());
        return Result.ok("删除成功");
    }

    @GetMapping("/listJson")
    @ApiOperation(value = "角色-列表(无分页)")
    public Result<List<SysRole>> listJson() {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getDataStatus, DataStatus.NORMAL.getValue());

        List<SysRole> roleList = sysRoleService.list(queryWrapper);
        return Result.data(roleList);
    }

    @GetMapping("/detail")
    @ApiOperation(value = "角色-详情")
    @PreAuthorize("@validate.hasPermission('system-role-detail')")
    public Result<SysRole> roleInfo(int id) {
        if (id <= 0) {
            return Result.error(SysRoleService.SYS_ROLE_NOT_EXIST);
        }
        SysRole role = sysRoleService.getById(id);
        if (role == null) {
            return Result.error(SysRoleService.SYS_ROLE_NOT_EXIST);
        }
        return Result.data(role);
    }
}
